CloudWatch アラームがアラーム状態になった際 EventBridge の入力トランスフォーマーを使わず Step Functions でメール件名と本文をカスタマイズし SNS からメール通知する
コーヒーが好きな emi です。
今更ですが、CloudWatch アラームがアラーム状態になった際 EventBridge から Step Functions でメール件名と本文をカスタマイズし SNS からメール通知する構成をやってみました。
EventBridge の入力トランスフォーマー(Input Transformer)や Lambda は使わず、Step Functions にメール件名と本文のカスタマイズ処理をさせます。
イメージ図と背景
以下のように、1 つの Step Function ステートマシンで SNS メール通知の件名と本文をカスタマイズします。
AWS からの通知を SNS 経由でメール受信すると、件名がデフォルトの『AWS Notification Message』となり、内容がわかりにくかったり、本文にそのまま JSON が貼り付けられて見づらいことがあります。
Lambda を使えば通知の柔軟なカスタマイズが可能ですが、コードやライブラリバージョンの管理が必要です。できれば Step Functions にすべての処理をお任せしたいです。
また、EventBridge の入力トランスフォーマー(Input transformer)でメールの本文をカスタマイズする場合、各 Event 毎に入力トランスフォーマーを設定する必要があります。
できればこちらも毎回設定するのではなく、1 つの Step Functions ステートマシンにメール件名と本文のカスタマイズをお任せしたいです。また、EventBridge だけではメールの件名までカスタマイズできないので、やはり Step Functions が必要です。
SNS トピックとサブスクリプションの作成
では SNS トピックとサブスクリプションを作成していきます。SNS コンソールで「トピックの作成」をクリックします。
スタンダードトピックを選択し、トピック名と表示名を設定して作成します。
サブスクリプションも作成します。
今回は E メールを選択して作成します。
サブスクリプションのステータスが「保留中の確認」になります。
以下の手順で、メール通知の停止(Unsubscribe)リンクを無効化した状態でサブスクリプションを確認します。
上記ブログの手順で確認すると、メール通知の停止(Unsubscribe)リンクを無効化した状態でサブスクリプションが「確認済み」になります。
Step Functions ステートマシンの作成
Step Functions コンソールでステートマシンを作成します。
テンプレートがいろいろありますが、「Blank」のまま「選択」で進みます。
コードで以下を貼り付けます。
{
"Comment": "CloudWatch Alarm Notification Workflow",
"StartAt": "Check Alarm State",
"States": {
"Check Alarm State": {
"Type": "Choice",
"Choices": [
{
"Variable": "$.detail.state.value",
"StringEquals": "ALARM",
"Next": "Format Message"
}
],
"Default": "Do Nothing"
},
"Format Message": {
"Type": "Pass",
"Parameters": {
"subject.$": "States.Format('CloudWatchアラーム通知: {}', $.detail.alarmName)",
"message.$": "States.Format('アラーム名: {}\n状態: {}\n理由: {}\n時刻: {}', $.detail.alarmName, $.detail.state.value, $.detail.state.reason, $.time)"
},
"Next": "Send SNS"
},
"Send SNS": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"TopicArn": "arn:aws:sns:ap-northeast-1:123456789012:SNS-Step-Functions-format-test",
"Message.$": "$.message",
"Subject.$": "$.subject"
},
"End": true
},
"Do Nothing": {
"Type": "Pass",
"End": true
}
}
}
"TopicArn"
には作成した SNS トピックの ARN を入力してください。
画面上部のステートマシン名の横の鉛筆マークをクリックすると、ステートマシンの設定画面が開きます。
- ステートマシン名:任意のステートマシン名を入力します。
- タイプ:標準
- 実行ロール:新しいロールを作成
- ログレベル:ERROR
- ステートマシンの実行が失敗したときのために ERROR ログに実行データを含めて保存します。システムの要件に合わせてカスタムしてください。
- CloudWatch ロググループ:新しいロググループを作成
他の設定値はデフォルトで「確認」をクリックします。
ステートマシンができるまで 1 分ほどかかります。
ステートマシンの IAM ロールは以下のような権限が付与されて作成されます。
許可
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogDelivery",
"logs:GetLogDelivery",
"logs:UpdateLogDelivery",
"logs:DeleteLogDelivery",
"logs:ListLogDeliveries",
"logs:PutResourcePolicy",
"logs:DescribeResourcePolicies",
"logs:DescribeLogGroups"
],
"Resource": "*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"sns:Publish"
],
"Resource": [
"arn:aws:sns:ap-northeast-1:123456789012:SNS-Step-Functions-format-test"
]
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"xray:PutTraceSegments",
"xray:PutTelemetryRecords",
"xray:GetSamplingRules",
"xray:GetSamplingTargets"
],
"Resource": [
"*"
]
}
]
}
信頼関係
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "states.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
ステートマシンのテスト実行
Step Functions ステートマシンが正しく作成できたかテスト実行してみます。テスト実行のためにサンプルの入力をコピーします。
サンプルの入力コードは EventBridge からコピーします。EventBridge ルールで「ルールの作成」をクリックします。
途中でキャンセルするので名前は適当で、他はそのまま次へ進みます。
サンプルイベントで「AWS イベント」、「CloudWatch Alarm State Change」を選択すると、サンプルイベントが表示されます。これをコピーしてテキストにメモしておきます。メモできたら、キャンセルをクリックしてルールの作成をやめます。
Step Functions ステートマシンのコンソールに戻ります。「実行を開始」をクリックします。
「入力 - オプション」に、コピーしたサンプルイベントを貼り付けて「実行を開始」をクリックします。
実行が成功するはずです。
メールを見ると、Step Functions ステートマシンの作成時に設定した通りにカスタマイズされたメールが届いています。
CloudWatch アラームの作成
通知させる CloudWatch アラームを作成します。何でもよいのですが、今回は適当な EC2 インスタンスの CPUUtilization のアラームを設定しましょう。EC2 インスタンスの「モニタリング」で CPU 使用率を展開します。
「メトリクスで表示」をクリックし、
「アクション」のベルマークをクリックしてアラームを作成します。
統計は最大にしておきました。
10% を超えたときにアラーム状態になるように設定します。
アクションの設定では何も設定しなくて OK です。「通知」は右上の「削除」をクリックして削除しておきます。
アクションに何も設定されていない状態になりました。「次へ」をクリックします。
アラーム名を設定し「次へ」をクリックすると確認画面に遷移します。そのままアラームを作成します。
作成されたアラームの詳細で画面下部の「EventBridge ルールを表示」をクリックすると、EventBridge ルールを作成する際に必要になるカスタムイベントパターンが表示されます。これをコピーしてテキストにメモしておきます。
こんな感じのカスタムイベントパターンがコピーできます。
{
"source": [
"aws.cloudwatch"
],
"detail-type": [
"CloudWatch Alarm State Change"
],
"resources": [
"arn:aws:cloudwatch:ap-northeast-1:123456789012:alarm:<アラーム名>"
]
}
EventBridge ルールの作成
EventBridge ルールを作成します。EventBridge コンソールで「ルールを作成」をクリックします。
名前、説明を入力します。ルールタイプは「イベントパターンを持つルール」を選択して「次へ」をクリックします。
イベントソースは「その他」を選択し、
そのままスクロールしてイベントパターンを入力します。先ほど CloudWatch アラームの作成時にコピーしておいたイベントパターンを貼り付けます。
ターゲットの選択では作成した Step Functions ステートマシンを選択します。実行ロールは新しいロールを作成を選択します。
「ターゲット入力を設定」で「一致したイベント」になっているのを確認し「次へ」をクリックします。
確認画面が表示されます。
「ルールの作成」をクリックします。
EventBridge ルールができました。
「イベントパターン」タブはこのようになっています。
「ターゲット」タブはこのようになっています。
EventBridge ルールターゲットタブに表示されている IAM ロールは以下のような権限が付与されています。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"states:StartExecution"
],
"Resource": [
"arn:aws:states:ap-northeast-1:123456789012:stateMachine:SNS-Step-Functions-format-test"
]
}
]
}
信頼関係
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
CloudWatch アラームをアラーム状態にする
CloudWatch アラームをアラーム状態にして、カスタマイズされた件名と本文のメールが通知されるか確認します。実際に EC2 に負荷をかけてもいいのですが、アラーム状態を変更する API があるのでこれを使います。詳細は以下のブログを参照ください。
AWS CLI からアラームの状態を変更します。
CloudShell で、以下のコマンドを実行します。
aws cloudwatch set-alarm-state \
--alarm-name "<アラーム名>" \
--state-value ALARM \
--state-reason "test"
実行結果例
[cloudshell-user@ip-10-130-33-150 ~]$ aws cloudwatch set-alarm-state \
> --alarm-name "EC2 CPUUtilization" \
> --state-value ALARM \
> --state-reason "test"
[cloudshell-user@ip-10-130-33-150 ~]$
上記コマンドを実行すると、一時的にアラーム状態になります。
アラーム状態はすぐに正常に戻ります。
メール通知確認
カスタマイズされた件名と本文のメール通知が受信できました。
参考